package cn.org.timespace.easyframe.util.chart;

import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Point;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.entity.StandardEntityCollection;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.labels.StandardXYToolTipGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.category.BarRenderer3D;
import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
import org.jfree.chart.servlet.ChartDeleter;
import org.jfree.chart.servlet.ServletUtilities;
import org.jfree.chart.urls.StandardPieURLGenerator;
import org.jfree.chart.urls.TimeSeriesURLGenerator;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.general.DatasetUtilities;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.general.DefaultValueDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.experimental.chart.plot.dial.DialBackground;
import org.jfree.experimental.chart.plot.dial.DialCap;
import org.jfree.experimental.chart.plot.dial.DialPlot;
import org.jfree.experimental.chart.plot.dial.DialTextAnnotation;
import org.jfree.experimental.chart.plot.dial.DialValueIndicator;
import org.jfree.experimental.chart.plot.dial.SimpleDialFrame;
import org.jfree.experimental.chart.plot.dial.StandardDialRange;
import org.jfree.experimental.chart.plot.dial.StandardDialScale;
import org.jfree.ui.GradientPaintTransformType;
import org.jfree.ui.StandardGradientPaintTransformer;

public class ChartUtil {

	/**
	 * 根据数据原 生成图片数据 返回图片名 3D 饼状图
	 * 
	 * @param map
	 *            存放要显示在页面上的内容和值
	 * @param title
	 *            　　　报表标题
	 * @param width
	 *            　　　　　　
	 * @param height
	 * @param session
	 * @param pw
	 *            　　　　
	 * @return 
	 *         返回一个图片名称，然后只需要将它放在request里(getRequest().setAttribute("filename",fileName
	 *         );)，然后在页面里如下调用即可 以下为实例： java代码： public String demo() throws
	 *         Exception { Map map=new HashMap(); map.put("中国", "1");
	 *         map.put("美国", "2"); map.put("欧洲", "3"); String
	 *         fileName=ChartUtil.generatePieChart(getRequest(), map, "全球经济报告",
	 *         500, 300); getRequest().setAttribute("filename",fileName); return
	 *         "demo"; } jsp页面： <img
	 *         src="${ctx }/servlet/DisplayChart?filename=${filename}" width=500
	 *         height=300 border=0>
	 */
	public static String generate3DPieChart(HttpServletRequest request,Map map, String title, int width, int height) {

		String filename = null;
		try {
			DefaultPieDataset dataset = new DefaultPieDataset();
			Set<String> set = map.keySet();
			for (String key : set) {
				dataset.setValue(key, new Double((String) map.get(key)));
			}
			HttpSession session = request.getSession();
			if (session != null) {
				ChartDeleter deleter = (ChartDeleter) session
						.getAttribute("JFreeChart_Deleter");
				session.removeAttribute("JFreeChart_Deleter");
				session.setAttribute("JFreeChart_Deleter", deleter);
				JFreeChart chart = ChartFactory.createPieChart3D(title, // chart
																		// title
						dataset, // data
						true, // include legend
						true, false);
				PiePlot plot = (PiePlot) chart.getPlot();
				plot.setSectionOutlinesVisible(false);
				plot.setLabelFont(new Font("SansSerif", Font.PLAIN, 12));
				plot.setNoDataMessage("没有数据");
				plot.setCircular(false);
				plot.setLabelGap(0.02);

				// 指定Section标签格式
				// plot.setLabelGenerator(PieSectionLabelGenerator);
				plot.setLabelGenerator(new StandardPieSectionLabelGenerator("{0}:{2}"));// {0}名称{1}占的数目{2}百分比{3}总和 控制界面显示的格式
				
				// Write the chart image to the temporary directory
				ChartRenderingInfo info = new ChartRenderingInfo(
						new StandardEntityCollection());
				filename = ServletUtilities.saveChartAsPNG(chart, width,
						height, info, session);

				PrintWriter pw = new PrintWriter("test.png");
				ChartUtilities.writeImageMap(pw, filename, info, true);
				pw.flush();
			}
		} catch (Exception e) {
			e.printStackTrace();
			filename = "picture_error.png";
		}
		return filename;

	}

	/**
	 * 生成柱状图
	 * 
	 * @param defaultCategoryDataset
	 * @param title
	 * @param width
	 * @param height
	 * @param session
	 * @param 范例：
	 * String[] rowKeys = {"苹果", "梨子", "葡萄"};    
		String[] columnKeys = {"北京", "上海", "广州", "成都", "深圳"};
		double[][] data = new double[][] { {672, 766, 223, 540, 126}, {325, 521,    
            210, 340, 106}, {332, 256, 523, 240, 526}};    
		String fileName=ChartUtil.generateBarChart(getRequest(),rowKeys,columnKeys,data,"中国水果市场调查",500,300);
		getRequest().setAttribute("filename",fileName);
	 * @return
	 * @throws IOException 
	 */
	public static String generateBarChart(HttpServletRequest request,String[] rowKeys,String[] columnKeys, double[][] data,String title,int width, int height) throws IOException {
		  
		  CategoryDataset dataset = DatasetUtilities.createCategoryDataset(rowKeys, columnKeys, data);;     


			JFreeChart chart = ChartFactory.createBarChart3D(title,    
			    null,    
			    null,    
			    dataset,    
			    PlotOrientation.VERTICAL,    
			    true, false, false);;    
			chart.setBackgroundPaint(Color.WHITE);;    
			CategoryPlot plot = chart.getCategoryPlot();;    
			
			CategoryAxis domainAxis = plot.getDomainAxis();;    
			//domainAxis.setVerticalCategoryLabels(false);;    
			plot.setDomainAxis(domainAxis);;    
			
			ValueAxis rangeAxis = plot.getRangeAxis();;    
			//设置最高的一个 Item 与图片顶端的距离    
			rangeAxis.setUpperMargin(0.15);;    
			//设置最低的一个 Item 与图片底端的距离    
			rangeAxis.setLowerMargin(0.15);;    
			plot.setRangeAxis(rangeAxis);;    
			
			BarRenderer3D renderer = new BarRenderer3D();;    
			renderer.setBaseOutlinePaint(Color.BLACK);;    
			//设置 Wall 的颜色    
			renderer.setWallPaint(Color.gray);;    
			//设置每种代表的柱的颜色    
			int length=rowKeys.length;
			for(int i=0;i<length;i++){
				renderer.setSeriesPaint(i, new Color(255-i*100,0,i*100));
			}  
			//设置每个地区所包含的平行柱的之间距离    
			renderer.setItemMargin(0.1);;    
			//显示每个柱的数值，并修改该数值的字体属性    
			renderer.setItemLabelGenerator(new StandardCategoryItemLabelGenerator()); 
			renderer.setItemLabelFont(new Font("黑体", Font.PLAIN, 20));   
			renderer.setItemLabelsVisible(true);;    
			plot.setRenderer(renderer);;    
			
			//设置柱的透明度    
			plot.setForegroundAlpha(0.6f);;    
			//设置显示的位置    
			plot.setDomainAxisLocation(AxisLocation.TOP_OR_RIGHT);;    
			plot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_RIGHT);;    
		
			HttpSession session = request.getSession();
			String filename = ServletUtilities.saveChartAsPNG(chart,width, height, null,session);;    
			String graphURL = request.getContextPath()+"/servlet/DisplayChart?filename=" + filename;
		    return graphURL;
	}

	/**
	 * 生成曲线图
	 * 
	 * @param defaultCategoryDataset
	 * @param title
	 * @param width
	 * @param height
	 * @param session
	 * @param 范例：
	 * Map map=new HashMap();
		map.put("1", "100");
		map.put("2", "200");
		map.put("3", "200");
		
		Map map1=new HashMap();
		map1.put("1", "150");
		map1.put("2", "250");
		map1.put("3", "250");
		
    	Map map2=new HashMap();
		map2.put("短信",map);
		map2.put("彩信",map1);
		String fileName=ChartUtil.generateDayLine(getRequest(),"信息发送量",map2);
		getRequest().setAttribute("filename",fileName);
	 * @return
	 */

	public static String generateDayLine(HttpServletRequest request,String title,Map map) {
		
		XYSeriesCollection xyDataset = new XYSeriesCollection(); 
		

		Set<String> set = map.keySet();
		for (String key : set) {
			XYSeries dataSeries = new XYSeries(key);
			Map map1=(Map)map.get(key);
			
			Set<String> set1 = map1.keySet();
			for(String key1 : set1){
				dataSeries.add(Integer.parseInt(key1),Integer.parseInt(((String) map1.get(key1))));
			}
			xyDataset.addSeries(dataSeries);
		}
		
		String graphURL = ""; 
		SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy", Locale.UK); 
		StandardXYToolTipGenerator ttg = new StandardXYToolTipGenerator(StandardXYToolTipGenerator.DEFAULT_TOOL_TIP_FORMAT,sdf,NumberFormat.getInstance()); 

		TimeSeriesURLGenerator urlg = new TimeSeriesURLGenerator(sdf, "pie_chart.jsp", "series", "hitDate"); 
		//  Create the chart object 

		ValueAxis xAxis = new NumberAxis("X轴坐标"); 
		//x轴坐标 
		ValueAxis yAxis = new NumberAxis("Y轴坐标"); 
		//y轴坐标 
		StandardXYItemRenderer renderer = new StandardXYItemRenderer(StandardXYItemRenderer.LINES ,ttg, urlg); 
		renderer.setShapesFilled(true); 
		             
		Font font=new Font("黑体",Font.TRUETYPE_FONT, 12); 
		XYPlot plot = new XYPlot(xyDataset, xAxis, yAxis, renderer); 
		JFreeChart chart = new JFreeChart(title, font, plot, true); 
		chart.setBackgroundPaint(java.awt.Color.white);             

		//  Write the chart image to the temporary directory 
		ChartRenderingInfo info = new ChartRenderingInfo(new StandardEntityCollection()); 
		try {
			HttpSession session = request.getSession();
			String filename = ServletUtilities.saveChartAsPNG(chart, 500, 300, info, session);
			graphURL = request.getContextPath()+"/servlet/DisplayChart?filename=" + filename;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return graphURL;
	}
	
	/**
	 *  用于开发仪表盘
	 *  String fileName=ChartUtil.generateDashboard(getRequest(),"衡阳铁一中考勤统计","刷卡量",20D);
		getRequest().setAttribute("filename",fileName);
	 * */
	public static String generateDashboard(HttpServletRequest request,String title,String title1,double number) {
		//数据集合对象 此处为DefaultValueDataset
        DefaultValueDataset dataset = new DefaultValueDataset();
        //当前指针指向的位置，即：我们需要显示的数据
        dataset = new DefaultValueDataset(number);
        //实例化DialPlot
        DialPlot dialplot = new DialPlot();
        dialplot.setView(0.0D, 0.0D, 1.0D, 1.0D);
        //设置数据集合
        dialplot.setDataset(dataset);
        //开始设置显示框架结构
        SimpleDialFrame simpledialframe = new SimpleDialFrame();
        simpledialframe.setBackgroundPaint(Color.lightGray);
        simpledialframe.setForegroundPaint(Color.darkGray);
        dialplot.setDialFrame(simpledialframe);
         //结束设置显示框架结构           
        GradientPaint gradientpaint = new GradientPaint(new Point(), new Color(255, 255, 255), new Point(), new Color(170, 170, 220));
        DialBackground dialbackground = new DialBackground(gradientpaint);
        dialbackground.setGradientPaintTransformer(new StandardGradientPaintTransformer(GradientPaintTransformType.VERTICAL));
        dialplot.setBackground(dialbackground);
        //设置显示在表盘中央位置的信息
        DialTextAnnotation dialtextannotation = new DialTextAnnotation(title1);
        dialtextannotation.setFont(new Font("Dialog", 1, 14));
        dialtextannotation.setRadius(0.69999999999999996D);
        dialplot.addLayer(dialtextannotation);
        DialValueIndicator dialvalueindicator = new DialValueIndicator(0, "c");
        dialplot.addLayer(dialvalueindicator);
        //根据表盘的直径大小（0.88），设置总刻度范围
        StandardDialScale standarddialscale = new StandardDialScale(-40D, 100D, -120D, -300D);
        standarddialscale.setTickRadius(0.88D);
        standarddialscale.setTickLabelOffset(0.14999999999999999D);
        standarddialscale.setTickLabelFont(new Font("Dialog", 0, 14));
        //主意是 dialplot.addScale（）不是dialplot.addLayer（）
        dialplot.addScale(0, standarddialscale);
        //设置刻度范围（红色）
        StandardDialRange standarddialrange = new StandardDialRange(40D, 100D, Color.red);
        standarddialrange.setInnerRadius(0.52000000000000002D);
        standarddialrange.setOuterRadius(0.55000000000000004D);
        dialplot.addLayer(standarddialrange);
        //设置刻度范围（橘黄色）           
        StandardDialRange standarddialrange1 = new StandardDialRange(10D, 50D, Color.orange);
        standarddialrange1.setInnerRadius(0.52000000000000002D);
        standarddialrange1.setOuterRadius(0.55000000000000004D);
        dialplot.addLayer(standarddialrange1);
        //设置刻度范围（绿色）               
        StandardDialRange standarddialrange2 = new StandardDialRange(-40D, 10D, Color.green);
        standarddialrange2.setInnerRadius(0.52000000000000002D);
        standarddialrange2.setOuterRadius(0.55000000000000004D);
        dialplot.addLayer(standarddialrange2);
        //设置指针
        org.jfree.experimental.chart.plot.dial.DialPointer.Pointer pointer = new org.jfree.experimental.chart.plot.dial.DialPointer.Pointer();
        dialplot.addLayer(pointer);
        //实例化DialCap
        DialCap dialcap = new DialCap();
        dialcap.setRadius(0.10000000000000001D);
        dialplot.setCap(dialcap);
        //生成chart对象
        JFreeChart jfreechart = new JFreeChart(dialplot);
        //设置标题
        jfreechart.setTitle(title);
   
        HttpSession session = request.getSession();
        String graphURL="";
		try {
			String filename = ServletUtilities.saveChartAsPNG(jfreechart, 400, 300, session);
			graphURL = request.getContextPath() + "/servlet/DisplayChart?filename=" + filename;
		} catch (IOException e) {
			e.printStackTrace();
		}
        //调用DisplayChart（配置在web.xml中），生成图形
        return graphURL;

	}
}
